package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.zzyl.constant.CacheConstant;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.ResourceDto;
import com.zzyl.entity.Resource;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.ResourceMapper;
import com.zzyl.service.ResourceService;
import com.zzyl.utils.EmptyUtil;
import com.zzyl.utils.NoProcessing;
import com.zzyl.utils.StringUtils;
import com.zzyl.vo.ResourceVo;
import com.zzyl.vo.TreeItemVo;
import com.zzyl.vo.TreeVo;
import jdk.dynalink.linker.LinkerServices;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;


import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ResourceServiceImpl implements ResourceService {

    @Autowired
    private ResourceMapper resourceMapper;
    /*
     * 多条件查询资源列表
     */
    @Cacheable(value = CacheConstant.RESOURCE_LIST,key = "#resourceDto.hashCode()")
    @Override
    public List<ResourceVo> findResourceList(ResourceDto resourceDto) {
        List<Resource> resourceList = resourceMapper.selectList(resourceDto);
        return BeanUtil.copyToList(resourceList, ResourceVo.class);

    }


    /*
     * 资源树形结构返回
     */
    @Cacheable(value = CacheConstant.RESOURCE_TREE)
    @Override
    public TreeVo resourceTreeVo(ResourceDto resourceDto) {
        ResourceDto dto = ResourceDto.builder()
                .dataState(SuperConstant.DATA_STATE_0)
                .parentResourceNo(NoProcessing.processString(SuperConstant.ROOT_PARENT_ID))
                .resourceType(SuperConstant.MENU).build();
        //查询所有菜单
        List<Resource> resourceList = resourceMapper.selectList(dto);
        if (EmptyUtil.isNullOrEmpty(resourceList)){
            throw new RuntimeException("菜单数据没有定义！");
        }
        //构建根节点
        Resource rootResource = new Resource();
        rootResource.setResourceNo(SuperConstant.ROOT_PARENT_ID);
        rootResource.setResourceName("指挥养老院");

        //返回的树形集合
        List<TreeItemVo> treeItemVos = new ArrayList<>();

        //使用递归构建树形结构
        recursionTreeItem(treeItemVos,rootResource,resourceList);

        return TreeVo.builder().items(treeItemVos).build() ;
    }

    /*
    *使用递归构建树形结构
     */
    private void recursionTreeItem( List<TreeItemVo> treeItemVos, Resource rootResource,List<Resource> resourceList) {
        //构建每个资源的属性
        TreeItemVo treeItemVo = TreeItemVo.builder()
                .id(rootResource.getResourceNo())
                .label(rootResource.getResourceName())
                .build();
        //获取当前资源的子资源
        List<Resource> children = resourceList.stream()
                .filter(resource -> resource.getParentResourceNo().equals(rootResource.getResourceNo()))
                .collect(Collectors.toList());
        //判断是否有子资源
        if (!EmptyUtil.isNullOrEmpty(children)){
            List<TreeItemVo> listChildren = new ArrayList<>();
            //构建子资源
            children.forEach(resource -> {
                recursionTreeItem(listChildren,resource, resourceList);
            });
            treeItemVo.setChildren(listChildren);
        }

        //添加到集合中
        treeItemVos.add(treeItemVo);
    }


    /*
    * 资源添加
     */
    @Caching(evict = {
            @CacheEvict(value = CacheConstant.RESOURCE_LIST,allEntries = true),
            @CacheEvict(value = CacheConstant.RESOURCE_TREE,allEntries = true)
    })
    @Override
    public void createResource(ResourceDto resourceDto) {
        //属性拷贝
        Resource resource = BeanUtil.toBean(resourceDto, Resource.class);
        //查询父资源
        Resource parentResource = resourceMapper.selectByResourceNo(resource.getParentResourceNo());
        resource.setDataState(parentResource.getDataState());
        boolean isIgnore = true;
        //判断是否是按钮
        if (StringUtils.isNotEmpty(resourceDto.getResourceType())
                && resourceDto.getResourceType().equals(SuperConstant.BUTTON))
         {
                isIgnore = false;
        }
        //创建当前资源的编号
        String resourceNo = createResourceNo(resourceDto.getParentResourceNo(), isIgnore);
        resource.setResourceNo(resourceNo);


        resourceMapper.insert(resource);
    }


    /*
    * 资源更新
     */
    @Caching(evict = {
            @CacheEvict(value = CacheConstant.RESOURCE_LIST,allEntries = true),
            @CacheEvict(value = CacheConstant.RESOURCE_TREE,allEntries = true)
    })
    @Override
    public void updateResource(ResourceDto resourceDto) {

        Resource resource = BeanUtil.toBean(resourceDto, Resource.class);
        resourceMapper.updateByPrimaryKeySelective(resource);

    }


    /*
    * 删除资源
     */
    @CacheEvict(value = CacheConstant.RESOURCE_LIST,allEntries = true)
    @Override
    public void deleteResource(String resourceNo) {
        Resource resource = resourceMapper.selectByNo(resourceNo);
        resourceMapper.deleteByPrimaryKey(resource.getId());
    }

    /*
    * 资源启用
     */
    @Caching(evict = {
            @CacheEvict(value = CacheConstant.RESOURCE_LIST,allEntries = true),
            @CacheEvict(value = CacheConstant.RESOURCE_TREE,allEntries = true)
    })
    @Override
    public void enableResource(ResourceDto resourceDto) {
        Resource resource = resourceMapper.selectByResourceNo(resourceDto.getResourceNo());
        resource.setDataState(resourceDto.getDataState());
        resourceMapper.updateByPrimaryKeySelective(resource);

        // 只有当禁用父资源时，才递归禁用所有子资源
        if (!SuperConstant.DATA_STATE_0.equals(resourceDto.getDataState())) {
            disableChildrenResources(resource.getResourceNo(), resourceDto.getDataState());
        }

    }

    /*
    * 创建资源编号
     */
    private String createResourceNo(String parentResourceNo, boolean isIgnore) {
        //100 001 000 000 000 根
        //100 001 001 000 000 第一层级
        if (isIgnore && NoProcessing.processString(parentResourceNo).length() / 3 >= 5){
            throw new BaseException(BasicEnum.RESOURCE_DEPTH_UPPER_LIMIT);
        }

        //根据父资源编号查询子资源
        ResourceDto dto = ResourceDto.builder().parentResourceNo(parentResourceNo).build();
        List<Resource> resourceList = resourceMapper.selectList(dto);
        if (EmptyUtil.isNullOrEmpty(resourceList)){
            //无下属节点，创建新节点
            return NoProcessing.createNo(parentResourceNo,false);
        }else{
            //有下属节点，在已有节点追加
            //获取最大值
            Long maxNo = resourceList.stream()
                    .map(resource -> {
                        return Long.valueOf(resource.getResourceNo());
                    }).max(Comparator.comparing(i -> i)).get();
            return NoProcessing.createNo(maxNo.toString(),true);

        }
    }

    /**
     * 递归禁用所有子资源
     */
    private void disableChildrenResources(String parentResourceNo, String dataState) {
        // 查询直接子资源
        ResourceDto queryDto = ResourceDto.builder().parentResourceNo(parentResourceNo).build();
        List<Resource> children = resourceMapper.selectList(queryDto);

        // 更新子资源状态并递归处理孙子资源
        for (Resource child : children) {
            child.setDataState(dataState);
            resourceMapper.updateByPrimaryKeySelective(child);

            // 递归处理子资源的子资源
            disableChildrenResources(child.getResourceNo(), dataState);
        }
    }

}
